<?php
/**
 * Albireo Kernel
 *
 * @copyright  Copyright (c) 2010 Albireo Solutions
 * @package    Webtop
 */

namespace WebtopModule\DesktopModule;

use Nette\Object;
use Nette\Collections\ArrayList;
use WebtopModule\DesktopModule\Icon;
use WebtopModule\DesktopModule\QuickLaunch;
use WebtopModule\DesktopModule\StartMenu;
use WebtopModule\DesktopModule\Window;
use \Exception;
use \dibi;
use \DibiException;

use WebtopModule\DesktopModule\Desktop;

/**
 * Desktop Management
 *
 * @author Albireo Solutions
 */

class DesktopManagement extends Object implements IDesktopManager {
    const QUICK_LAUNCHES = "quick_launches";
    const ICONS = "icons";
    const WINDOWS = "windows";
    const START_MENUS = "start_menus";
    const DESKTOPS = "desktops";

    /** @var Desktop */
    private $desktop;

    public function __construct($id) {
        $this->desktop = new Desktop();
        $this->desktop->setId($id);
    }

    /**
     * @var Desktop
     */
    private $desktop;

    public function __construct($id) {
        $this->desktop = new Desktop();
        $this->desktop->setId($id);
    }
    
    public function getAllDesktops() {
        
    }


    public function getDesktop() {
        return $this->desktop;
    }

    public function getDesktop() {
        return $this->desktop;
    }
    
    public function loadDesktop() {
        $this->loadIconsForDesktop();
        $this->loadQuickLaunchesForDesktop();
        $this->loadStartMenusForDesktop();
        $this->loadWindowsForDesktop();

        $row = dibi::select("*")->from(self::DESKTOPS)->
                where("%and", array("desktop_id" => $this->desktop->getId()))->fetch();
        $desktop = $this->dibiRowToDesktop($row);
        $this->desktop->setUser($desktop->getUser());
        $this->desktop->setColor($desktop->getColor());
        $this->desktop->setBackgroundImage($desktop->getBackgroundImage());
        $this->desktop->setBackgroundImageStyle($desktop->getBackgroundImageStyle());
        $this->desktop->setPanelPosition($desktop->getPanelPosition());
        $this->desktop->setPanelSize($desktop->getPanelSize());
        $this->desktop->setSkin($desktop->getSkin());
    }

    private function dibiRowToDesktop($row, Desktop $desktop = null) {
        if ($desktop === null) {
            $desktop = new Desktop();
        }
        $desktop->setID($row->desktop_id);
        $desktop->setUser($row->user_id);
        $desktop->setColor($row->color);
        $desktop->setBackgroundImage($row->image);
        $desktop->setBackgroundImageStyle($row->stretch);
        $desktop->setPanelPosition($row->panel_position);
        $desktop->setPanelSize($row->panel_size);
        $desktop->setSkin($row->skin_id);
        return $desktop;
    }

   // are shortcuts for desktop getters - it is used for example when you only add quick launches
    // then you want to return quick launches
    public function loadQuickLaunchesForDesktop() {
	$rows = dibi::select("*")->from(self::QUICK_LAUNCHES)->
                where("%and", array("desktop_id" => $this->desktop->getId()))->fetchAll();
        $result = new ArrayList();
        foreach($rows as $row) {
            $result->append($this->dibiRowToQuickLaunch($row));
        }
        \Nette\Debug::dump($result);
        $this->desktop->setQuickLaunches($result);
    }

    private function dibiRowToQuickLaunch($row, QuickLaunch $ql = null) {
        if ($ql === null) {
            $ql = new QuickLaunch();
        }
        $ql->setID($row->quick_launch_id);
        $ql->setPreceder($row->preceder_id);
        $ql->setCommand($row->command);
        return $ql;
    }
    public function loadWindowsForDesktop() {
        $rows = dibi::select("*")->from(self::WINDOWS)->
                where("%and", array("desktop_id" => $this->desktop->getId()))->fetchAll();
        $result = new ArrayList();
        foreach($rows as $row) {
            $result->append($this->dibiRowToWindow($row));
        }
        \Nette\Debug::dump($result);
        $this->desktop->setWindows($result);
    }

    private function dibiRowToWindow($row, Window $window = null) {
        if ($window === null) {
            $window = new Window();
        }
        $window->getId($row->windiw_id);
        $window->setXPos($row->x_position);
        $window->setYPos($row->y_position);
        $window->setXSize($row->x_size);
        $window->setYSize($row->y_size);
        $window->setZLevel($row->z_level);
        $window->setMaximized($row->maximized);
        $window->setMinimized($row->minimized);
        $window->setProcess($row->proccess_id);
        return $window;
    }
    
    public function loadIconsForDesktop() {
        $rows = dibi::select("*")->from(self::ICONS)->
                where("%and", array("desktop_id" => $this->desktop->getId()))->fetchAll();
        $result = new ArrayList();
        foreach($rows as $row) {
            $result->append($this->dibiRowToIcon($row));
        }
        \Nette\Debug::dump($result);
        $this->desktop->setIcons($result);
    }

    private function dibiRowToIcon($row, Icon $icon = null) {
        if ($icon === null) {
            $icon = new Icon();
        }
        $icon->setId($row->icon_id);
        $icon->setXPos($row->x_position);
        $icon->setYPos($row->y_position);
        $icon->setCommand($row->command);
        return $icon;
    }
    
    public function loadStartMenusForDesktop() {
        $rows = dibi::select("*")->from(self::START_MENUS)->
                where("%and", array("desktop_id" => $this->desktop->getId()))->fetchAll();
        $result = new ArrayList();
        foreach($rows as $row) {
            $result->append($this->dibiRowToStartMenu($row));
        }
        \Nette\Debug::dump($result);
        $this->desktop->setStartMenus($result);
    }

    private function dibiRowToStartMenu($row, StartMenu $sm = null) {
        if ($sm === null) {
            $sm = new StartMenu();
        }
        $sm->setID($row->start_menu_id);
        $sm->setParent($row->parent_id);
        $sm->setPreceder($row->desktop_id);
        $sm->setCommand($row->command);
        return $sm;
    }

    // returns arraylist of the type for ex. quicklaunches... use getQLFD (declared 6 lines upper)
    public function addQuickLaunch(QuickLaunch $ql) {
	if($ql == NULL) {
	    throw new \Exception("Invalid attempt to write into DB.");
	}
	else {
	    try {
		dibi::query("INSERT INTO [" . self::QUICK_LAUNCHES . "]
		    ([quick_launch_id],[desktop_id],[preceder_id],[name_file]) VALUES
		    ([%iN],[%iN],[%sN])",$ql->getId(),$this->desktop->getId(),$ql->getPreceder()->getId(),$ql->getFile()->getFileURL());
	    }
	    catch(DibiException $exception) {
		throw $exception;
	    }
	}
    }

    public function updateQuickLaunch(QuickLaunch $ql) {
	if($ql == NULL) {
	    throw new \Exception("Invalid attempt to write into DB.");
	}
	else {
	    try {
		dibi::query("UPDATE [" . self::QUICK_LAUNCHES . "]
		SET [preceder_id]=" . $ql->getPreceder()->getId()
		    . "[command]=" . $ql->getFile() . "
		WHERE [quick_launch_id]=" . $ql->getId());
	    }
	    catch(DibiException $exception) {
		throw $exception;
	    }
	} 
    }

    public function removeQuickLaunch(QuickLaunch $ql) {
	if ($ql == NULL) {
            return false;
        }
        try {
            dibi::query("DELETE FROM [" . self::QUICK_LAUNCHES . "] WHERE [quick_launch_id] = %i", $ql->getId());
            return true;
        } catch (DibiException $e) {
            throw $e;
        }
    }
    
    public function addIcon(Icon $icon) {
	if($icon == NULL) {
	    throw new \Exception("Invalid attempt to write into DB.");
	}
	else {
	    try {
		dibi::query("INSERT INTO [" . self::ICONS . "]
		    ([icon_id],[desktop_id],[x_position],[y_position],[command]) VALUES
		    ([%iN],[%iN],[%iN],[%sN])",$icon->getId(),$this->desktop->getId(),$icon->getXPos(),$icon->getYPos(),$icon->getFile()->getFileURL());
	    }
	    catch(DibiException $exception) {
		throw $exception;
	    }
	}
    }

    public function updateIcon(Icon $icon) {
	if($icon == NULL) {
	    throw new \Exception("Invalid attempt to write into DB.");
	}
	else {
	    try {
		dibi::query("UPDATE [" . self::ICONS . "]
		SET [x_position]=" . $icon->getXPos()
		    . "[y_position]=" . $icon->getYPos()
	            . "[command]=" . $icon->getFile()->getFileURL() . "
		WHERE [icon_id]=" . $icon->getId());
	    }
	    catch(DibiException $exception) {
		print $exception->getMessage();
	    }
	}
    }

    public function removeIcon(Icon $icon) {
	if ($icon->getId() <= 0) {
            return false;
        }
        try {
            dibi::query("DELETE FROM [" . self::ICONS . "] WHERE [icon_id] = %i", $icon->getId());
            return true;
        } catch (DibiException $e) {
            throw $e;
        }
    }

    public function addWindow(Window $window) {
	if($window == NULL) {
	    throw new \Exception("Invalid attempt to write into DB.");
	}
	else {
	    try {
		dibi::query("INSERT INTO [" . self::WINDOWS . "]
		    ([window_id],[desktop_id],[x_position],[y_position],[x_size],[y_size],[z_level],[maximized],[minimized],[process_id]) VALUES
		    ([%iN],[%iN],[%iN],[%iN],[%iN],[%b],[%b],[%sN])",$window->getId(),$this->desktop->getId(),$window->getXPos(),$window->getYPos(),$window->getXSize(),$window->getYSize(),$window->getZLevel(),$window->getMaximized(),$window->getMinimized(),$window->getProcess());
	    }
	    catch(DibiException $exception) {
		throw $exception;
	    }
	}
    }

    public function updateWindow(Window $window) {
	if($window == NULL) {
	    throw new \Exception("Invalid attempt to write into DB.");
	}
	else {
	    try {
		dibi::query("UPDATE [" . self::WINDOWS . "]
		SET [x_position]=" . $window->getXPos()
		    . "[y_position]=" . $window->getYPos()
		    . "[x_size]=" . $window->getXSize()
		    . "[y_size]=" . $window->getYSize()
		    . "[z_level]" . $window->getZLevel()
		    . "[maximized]" . $window->getMaximized()
		    . "[minimized]" . $window->getMinimized()
	            . "[process_id]=" . $window->getProcess() . "
		WHERE [id_window]=" . $window->getId());
	    }
	    catch(DibiException $exception) {
                throw $exception;
	    }
	}
    }

    public function removeWindow(Window $window) {
	if ($window->getId() <= 0) {
            return false;
        }
        try {
            dibi::query("DELETE FROM [" . self::WINDOWS . "] WHERE [window_id] = %i", $window->getId());
            return true;
        } catch (DibiException $e) {
            throw $e;
        }
    }
    
    public function addStartMenu(StartMenu $sm) {
	if($sm == NULL) {
	    throw new \Exception("Invalid attempt to write into DB.");
	}
	else {
	    try {
		dibi::query("INSERT INTO [" . self::START_MENUS . "]
		    ([start_menu_id],[desktop_id],[parent_id],[preceder_id],[process]) VALUES
		    ([%iN],[%iN],[%iN],[%iN],[%sN])",$sm->getId(),$this->desktop->getId(),$sm->getParent()->getId(),$sm->getPreceder()->getId(),$sm->getFile()->getFileURL());
	    }
	    catch(DibiException $exception) {
		throw $exception;
	    }
	}
    }

    public function updateStartMenu(StartMenu $sm) {
	if($sm == NULL) {
	    throw new \Exception("Invalid attempt to write into DB.");
	}
	else {
	    try {
		dibi::query("UPDATE [" . self::WINDOWS . "]
		SET [parent_id]=" . $sm->getParent()->getId()
		    . "[preceder_id]=" . $sm->getPreceder()->getId()
		    . "[process]=" . $sm->getFile()->getFileURL() . "
		WHERE [start_menu_id]=" . $sm->getId());
	    }
	    catch(DibiException $exception) {
		throw $exception;
	    }
	}
    }
    
    public function removeStartMenu(StartMenu $sm) {
	if ($sm->getId() <= 0) {
            return false;
        }
        try {
            dibi::query("DELETE FROM [" . self::START_MENUS . "] WHERE [start_menu_id] = %i", $sm->getId());
            return true;
        } catch (DibiException $e) {
            throw $e;
        }
    }

    public function addDesktop() {

    }

    public function updateDesktop() {

    }

    public function removeDesktop() {
        
    }
}
